/**
 *@brief: socket's Server
**/

#include <stdio.h>
#include <sys/types.h>        
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>

#define SERVER_PORT			8888
#define MAX_BACKLOG			50

int main()
{
	int skt_fd = 0;
	int cnt_fd = 0;
	
	struct sockaddr_in server_sock = {0};
	struct sockaddr_in client_sock = {0};
	int ret = 0;
	char server_buf[512] = {0};
	socklen_t addrlen =  sizeof(client_sock);
	
	char ip_str[20] = {0};
	
	//1. 创建服务器的套接字(socket())
	//IPv4--TCP
	skt_fd = socket(AF_INET, SOCK_STREAM,0);
	if(skt_fd < 0)
	{
		perror("Socket create failed!");
		exit(-1);
	}
	
	//2. 进行 bind()， 指定服务器要侦听的 IP 地址和端口
	//x86 主机采用小端方式，而网络采用大端方式。
	server_sock.sin_family = AF_INET;
	server_sock.sin_addr.s_addr = htonl(INADDR_ANY); //侦听任意 IP 地址 
	server_sock.sin_port = htons(SERVER_PORT); //侦听端口为8888
	
	ret = bind(skt_fd, (struct sockaddr *)(&server_sock),  sizeof(server_sock));
	if(ret < 0)
	{
		perror("bind failed!");
		close(skt_fd);
		exit(-1);
	}

	//3. listen()进入监听状态
	listen(skt_fd, MAX_BACKLOG);
	
	//4. accept() 建立关系，获取客户端的 addr 于 client_sock 之中
	//并且得到新的 skt_fd
	cnt_fd = accept(skt_fd, (struct sockaddr *)(&client_sock), &addrlen);
	if(cnt_fd < 0)
	{
		perror("accept failed!");
		close(skt_fd);
		exit(-1);
	}
	
	printf("We have Client connected!\n");
	//IP 机器码转换为人类码存储于ip_str之中
	inet_ntop(AF_INET, (struct in_addr *)(&client_sock.sin_addr.s_addr),(char *)ip_str, sizeof(ip_str));
	printf("Client IP is %s\n", ip_str);
	printf("Client IP port is %d\n",client_sock.sin_port);
	
	//while()循环，不断读取从客户端来的数据
	while(1)
	{
		//bzero 清空缓存
		bzero(server_buf,  sizeof(server_buf));
		
		//ssize_t recv(int sockfd, void *buf, size_t len, int flags);
		//从 accept 返回的 cnt_fd 连接
		ret = recv(cnt_fd, server_buf, sizeof(server_buf), 0);
		if(ret < 0)
		{
			perror("recv/read failed!");
			exit(-1);
		}
		
		//比较是否是 exit,如果是则退出
		if(strncmp(server_buf, "exit", 4) != 0)
		{
			printf("Server got:%s\n", server_buf);
		}
		else // ==exit
		{
			close(cnt_fd);
			break;
		}
	}
	close(skt_fd);
	
	return 0;
}
